import { computed, getCurrentInstance, inject, isReactive, reactive, isRef } from 'vue'
import { piniaSymbol } from './piniaSymbol'

/**
 * defineStore接受三种传参方式
 * 第一种是传入id+options
 * 第二种是只传入options(而id包含在这个options内部),options是对象
 * 第三种是传入id+setup函数
 */

export function defineStore(idOrOptions, optionsOrSetup) {
    //单独定义id和Options
    let id, options
    //接受和处理第一个参数,id:string,options:object
    if (typeof idOrOptions == "string") {
        id = idOrOptions
        options = optionsOrSetup  //对象或函数
    } else {
        options = idOrOptions //对象
        id = options.id
    }

    //返回函数
    function useStore() {
        //当前组件实例是否存在
        const instance = getCurrentInstance() //获取当前组件实例
        let piniaStore = instance && inject(piniaSymbol)// 如果当前组件实例存在就注入整个piniaStore(因为只有在vue组件里才可以使用inject)
        if (!piniaStore._stores.has(id)) {//如何在piniastore的map中没有对应的id，则表示需要新建，如果已经存在则只需要返回数据
            //录入新的数据（state,actions,getters）包含的对象一起放入map中
            //id不存在则添加的是options数据
            if (typeof optionsOrSetup === "function") {//传入进来的是一个函数
                //将对应的id里的opints，放置到piniaStroe
                createSetupStore() //函数形式
            } else {//前两种传参方式都用这个来结构store
                //将对应的id里的opints，放置到piniaStroe
                createOptionsStore(id, options, piniaStore) //对象形式
            }
        }
        return piniaStore._stores.get(id) //获取目前use的这个store

        // let piniaStore = {
        //     ...options
        // }
        //return piniaStore
    }

    return useStore //用户使用这个函数就能获取 store实例对象

}
//处理函数式defineStore
function createSetupStore() {

}




/**defineStore传入了options时调用这个函数 （感觉传入options就是为了迎合vue2的写法）*/
function createOptionsStore() {

}

